package com.jjc.MyWebApp.Interceptor;

import com.alibaba.druid.util.H2Utils;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jjc.MyWebApp.Constant.ConfigConstant;
import com.jjc.MyWebApp.Constant.WebContextConstant;
import com.jjc.MyWebApp.Model.User;
import com.jjc.MyWebApp.Plugin.ServicePlugin;
import com.jjc.MyWebApp.Routes.BaseController;
import com.jjc.MyWebApp.Service.UserService;
import com.jjc.MyWebApp.kit.DateKit;
import com.jjc.MyWebApp.kit.IDEAKit;
import com.jjc.MyWebApp.kit.WebKit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 权限认证拦截器
 * Created by jiaji on 2017/5/10.
 */
public class AuthInterceptor implements Interceptor {
    private static final Log log = Log.getLog(AuthInterceptor.class);


    public void intercept(Invocation inv) {
        BaseController controller = (BaseController) inv.getController();
        User user=getCurrentUser(controller,false);
        controller.setAttr(WebContextConstant.current_User, user);
        inv.invoke();
    }

    /**
     * 设置当前登录用户
     *
     * @param controller 控制器
     * @param user       User
     * @param autoLogin  是否自动登录
     */
    public static void setCurrentUser(BaseController controller, User user, boolean autoLogin) {
        //设置Cookie有效时间
        int maxTime = -1;
        if (autoLogin) {
            maxTime = PropKit.getInt(ConfigConstant.config_cookie_maxTime);
        }

        //设置用户名到Cookie
        controller.setCookie("userName", user.getUserEmail(), maxTime);

        //生成登录认证用cookie

        //内层用户私有密钥加密
        String inner = new StringBuilder(controller.getRequest().getScheme())
                .append(".#.").append(new Date().getTime())
                .append(".#.").append(WebKit.getIpAddr(controller))
                .append(".#.").append(controller.getRequest().getHeader("User-Agent"))
                .append(".#.").append(autoLogin).toString();
        if (PropKit.getBoolean(ConfigConstant.config_devMode, false))
            log.info("setCurrentUser: 内层加密信息为:\n" + inner);
        inner = IDEAKit.encrypt(user.getUserSecuritykey(), inner);

        //外层公共密钥加密
        String outer = new StringBuilder(user.getUserId()).append(".#.").append(inner).toString();
        if (PropKit.getBoolean(ConfigConstant.config_devMode, false))
            log.info("setCurrentUser: 外层加密信息为:\n" + outer);
        outer = IDEAKit.encrypt(outer);

        controller.setCookie(WebContextConstant.cookie_authmark, outer, maxTime);
        controller.getResponse().setHeader(WebContextConstant.cookie_authmark, outer);
    }

    public static User getCurrentUser(BaseController controller, boolean userAgentVali) {

        UserService userService = (UserService) ServicePlugin.getService("userService");

        //获取加密串
        String LoginCookie = controller.getHeader(WebContextConstant.cookie_authmark);
        //如果获取不到，再从Cookie取
        if (StrKit.isBlank(LoginCookie)) {
            LoginCookie = controller.getCookie(WebContextConstant.cookie_authmark);
        }

        if (StrKit.isBlank(LoginCookie)) {
            controller.removeCookie(WebContextConstant.cookie_authmark);
            return null;
        }

        //解密外层认证数据
        String outer = IDEAKit.decrypt(LoginCookie);
        if (StrKit.isBlank(outer)) {
            controller.removeCookie(WebContextConstant.cookie_authmark);
            return null;
        }
        String[] outerArr = outer.split(".#."); //UserID .#. inner
        String secretkey = userService.CacheGetUserById(outerArr[0]).getUserSecuritykey();

        //得到内层数据
        String inner = IDEAKit.decrypt(secretkey, outerArr[1]);
        //分解认证数据，内层
        String[] innerArr = inner.split(".#.");        // arr[0]：scheme，arr[1]：时间戳，arr[2]：USER_IP， arr[3]：USER_AGENT， arr[4]：autoLogin
        String scheme = innerArr[0];                            // scheme
        long loginDateTimes = Long.parseLong(innerArr[1]);        // 时间戳

        String ips = innerArr[2];                                // ip地址
        String userAgent = innerArr[3];                        // USER_AGENT
        boolean autoLogin = Boolean.valueOf(innerArr[4]);        // 是否自动登录

        String newSchme = controller.getRequest().getScheme();
        String newUserAgent = controller.getRequest().getHeader("User-Agent");
        String newIps = WebKit.getIpAddr(controller);
        long MaxTime = PropKit.getLong(ConfigConstant.config_cookie_maxTime);

        if (StrKit.equals(scheme, newSchme)
                && StrKit.equals(ips, newIps)
                && (userAgentVali ? StrKit.equals(userAgent, newUserAgent) : true)
                && (new Date().getTime() - loginDateTimes) / 1000 <= MaxTime) {
            if (!autoLogin) {
                long session = PropKit.getLong(ConfigConstant.config_cookie_session);
                if ((new Date().getTime() - loginDateTimes) / 1000 >= session) {
                    return null;
                } else {
                    setCurrentUser(controller, userService.CacheUpdateById(outerArr[0]), autoLogin);
                }
            }
            return userService.CacheUpdateById(outerArr[0]);
        }
        return null;
    }
}

